package lab1;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;

import vs_a1.MessageServerInterface;

public class Client extends JPanel {

    /**
	 * 
	 */
    private static final long serialVersionUID = 1L;
    private JSplitPane splitpane;
    private JTextArea outputTextfield;
    private JTextArea inputTextfield;
    private JTextArea serverTextfield;
    private JButton sendMessage;
    private JButton getMessage;
    private JButton connect;
    private String clientID = "";
    private MessageServerInterface server;
    private final int allowedServerTimeout = 10;

    public Client() throws MalformedURLException, RemoteException, NotBoundException, AlreadyBoundException {
        buildView();
    }// Client

    private void buildView() {
        this.setLayout(new BorderLayout());
        splitpane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        outputTextfield = new JTextArea();
        outputTextfield.setEditable(false);
        outputTextfield.setBackground(Color.white);
        inputTextfield = new JTextArea();
        inputTextfield.setEditable(true);
        inputTextfield.setBackground(Color.white);
        serverTextfield = new JTextArea();
        serverTextfield.setEditable(true);
        serverTextfield.setBackground(Color.white);
        sendMessage = new JButton("Send message");
        getMessage = new JButton("Get new messages");
        connect = new JButton("Connect to server");
        sendMessage.addActionListener(new CallButtonActionListener());
        getMessage.addActionListener(new CallButtonActionListener());
        connect.addActionListener(new CallButtonActionListener());
        connect.setOpaque(true);
        JLabel jL = new JLabel("Server URL");
        JPanel jp = new JPanel(new BorderLayout());
        jp.add(jL, BorderLayout.WEST);
        jp.add(serverTextfield, BorderLayout.CENTER);
        jp.add(connect, BorderLayout.NORTH);
        jp.add(sendMessage, BorderLayout.SOUTH);
        jp.add(getMessage, BorderLayout.EAST);
        JSplitPane j = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        JScrollPane outPut = new JScrollPane(outputTextfield);
        j.add(outPut);
        j.add(inputTextfield);
        JScrollPane scTop = new JScrollPane(j);
        JScrollPane scBottom = new JScrollPane(jp);
        splitpane.add(scTop, JSplitPane.TOP);
        splitpane.add(scBottom, JSplitPane.BOTTOM);
        sendMessage.setEnabled(false);
        getMessage.setEnabled(false);
        this.add(splitpane, BorderLayout.CENTER);
        while (clientID == null || clientID.equals("")) {
            clientID = JOptionPane.showInputDialog(null, "Enter username");
        }// while
    }// buildView

    public static void main(String[] args) throws AlreadyBoundException {

        Client c;
        try {
            c = new Client();
            ShowInFrame.show("RMI Client - " + c.clientID, c);
        }catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }catch (NotBoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }// catch
    }// main

    /**
     * Inner class for CallButtonActionListener.<br>
     * Handles the events when a button is pressed.
     */
    private class CallButtonActionListener implements ActionListener {
        public void actionPerformed(ActionEvent ev) {
            JButton source = (JButton) ev.getSource();

            if (source.getText().contains("Send message")) {
                String input = inputTextfield.getText();
                try {
                    server.dropMessage(clientID, input);
                    inputTextfield.setText(null);
                    connect.setBackground(Color.green);
                }catch (RemoteException e) {
                    if (e.getMessage().contains("Connection refused")) {
                        checkServerConnection(input,false);
                    }// if
                }// catch
            }// if

            if (source.getText().contains("Get new messages")) {
                try {
                    
                    String message = server.getMessage(clientID);
                    if (message.equals("")) {
                        // do nothing
                    }else {
                        outputTextfield.append(message + "\n");
                    }//else
                }catch (RemoteException e) {
                    if (e.getMessage().contains("Connection refused")) {
                        checkServerConnection(null,true);
                    }else if(e.getMessage().contains("no more messages")){
                        JOptionPane.showMessageDialog(null, "No more messages", null,
                                JOptionPane.INFORMATION_MESSAGE);
                    }//if
                }// catch
            }// if
            if (source.getText().contains("Connect to server")) {
                try {
                    String s = serverTextfield.getText();
                    if (s.equals("")) {
                        JOptionPane.showMessageDialog(null, "Please enter a Server URL", null,
                                JOptionPane.WARNING_MESSAGE);
                    }else {
                        server = (MessageServerInterface) Naming.lookup(s);
                        connect.setBackground(Color.green);
                        outputTextfield.setText(null);
                        sendMessage.setEnabled(true);
                        getMessage.setEnabled(true);
                    }// else
                }catch (RemoteException e) {
                    JOptionPane.showMessageDialog(null, "Could not connect to Server", null, JOptionPane.ERROR_MESSAGE);
                    connect.setBackground(Color.red);
                    sendMessage.setEnabled(false);
                    getMessage.setEnabled(false);
                }// catch
                catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                    connect.setBackground(Color.red);
                    sendMessage.setEnabled(false);
                    getMessage.setEnabled(false);
                    System.out.println("In MalformedURLException");
                    System.out.println(e.getMessage());
                    // e.printStackTrace();
                }catch (NotBoundException e) {
                    connect.setBackground(Color.red);
                    sendMessage.setEnabled(false);
                    getMessage.setEnabled(false);
                    System.out.println("In NotBoundException");
                    System.out.println(e.getMessage());
                    // e.printStackTrace();
                }// catch
            }// if
        }// actionPerformed

        private void checkServerConnection(String input, boolean output) {
            int i = 0;
            connect.setBackground(Color.gray);
            connect.repaint();
            System.out.printf("Connection to Server lost...\nTrying to reestablish");
            for (i = 0; i != allowedServerTimeout; i++) {
                try {
                    System.out.printf(".");
                    Thread.sleep(1000);
                    String s = serverTextfield.getText();
                    server = (MessageServerInterface) Naming.lookup(s);
                    if(output){
                        String message = server.getMessage(clientID);
                        if (message.equals("")) {
                            // do nothing
                        }else {
                            outputTextfield.append(message + "\n");
                        }
                    }else{
                    server.dropMessage(clientID, input);
                    inputTextfield.setText(null);
                    }
                    connect.setBackground(Color.green);
                    System.out.println();
                    break;
                }catch (InterruptedException e1) {
                }catch (RemoteException e2) {
                }catch (MalformedURLException e3) {
                }catch (NotBoundException e4) {
                }// catch
            }// for
            if (i == allowedServerTimeout) {
                connect.setBackground(Color.red);
                System.out.println("\nConnection could not be established. Please try again later.");
            }// if
        }//checkServerConnection
    }// CallButtonActionListener
}